クロスアカウントでVPCピアリング先のEC2(MySQL)へLambdaからアクセスしてみる
こんにちは、鈴木(純)です。
クロスアカウントでVPCピアリングした環境で、LambdaからEC2内にインストールしたMySQLへアクセスしてみました。
はじめに
以下のような環境を想定しています。EC2インスタンス側のセキュリティグループでアカウントBのLambdaからのみアクセスを許可するようにインバウンドを絞っていきます。
LambdaからMySQLに登録したテーブルの情報をSELECTすることをゴールとします。
前提
今回はVPCピアリングの細かい話はしません。以下の記事みてもらえるとルーティングまで設定できるかと思います。
VPCピアリングした状態で、ルートテーブルが設定済の前提で進めます。
EC2(MySQL)へサンプルデータを用意する
まず最初にEC2(Amazon Linux2)を用意してMySQLをインストールします。
以下を参考にMySQLをインストール。
無事MySQLへログインできたら、サンプル用のnameテーブルを作成していきます。
$ use mysql; $ create table name (name varchar(10));
とりあえず、以下のような5つのデータを挿入。
insert into name values ('Suzuki'); insert into name values ('Satou'); insert into name values ('Kimura'); insert into name values ('Toda'); insert into name values ('Goto');
$ select * from name; +--------+ | name | +--------+ | Suzuki | | Satou | | Kimura | | Toda | | Goto | +--------+
上記のように表示されれば、サンプル用のテーブル作成は完了です。
Lambdaを作成する
次に先ほど作成したテーブルを読み取るLambdaを作成していきます。今回はpython3.7で作成していきます。
下へスクロールして詳細設定を開くとネットワークを設定することができるので、Lambda関数に紐づけるVPC、サブネット、セキュリティグループを設定します。ここでネットワークを設定することで、Lambda関数がプライベートサブネットへ接続できるようVPC内にENIが作成されます。詳しくは以下ドキュメントをご参照下さい。
Lambda関数に設定したセキュリティグループはインバウンド設定なし、アウトバウンドは制限をかけずにオープンにしてます。
Lambda用のコードを作成する
ここからはAWSのコンソールではなく、ローカルで作業して下さい。理由はMySQLへの接続で使用するパッケージをインストールする必要があり、ZIPの形式でLambdaへアップロードする必要があるためです。
任意のフォルダを作成します。
$ mkdir function $ cd function
以下のコードをlambda_function.py
として保存します。接続先については適宜変更して下さい。
$ vi lambda_function.py
import json import mysql.connector import traceback import sys def lambda_handler(event, context): names = "" conn = mysql.connector.connect(user='[ユーザー名]', password='[パスワード]', host='[接続先EC2のプライベートIP]', database='[DB名]') cur = None try: cur = conn.cursor(dictionary=True) cur.execute("select * from name;") for row in cur.fetchall(): names += row['name'] + "," cur.close except: traceback.print_exc() print(sys.exc_info()) names = "error!" finally: cur.close conn.close return { 'statusCode': 200, 'body': json.dumps('name : ' + names) }
MySQLへ接続するために、ライブラリをインストールします。
$ pip install mysql-connector-python -t . Collecting mysql-connector-python Using cached https://files.pythonhosted.org/packages/91/c3/d06afc12fb811e62732b5d0332648bb8a92f253eb45585042852156d3236/mysql_connector_python-8.0.23-cp36-cp36m-macosx_10_14_x86_64.whl Collecting protobuf>=3.0.0 (from mysql-connector-python) Using cached https://files.pythonhosted.org/packages/a7/04/82599fbac6f1e047242bb6e7a4fac76cb2a94a38968af30ee55a4179be31/protobuf-3.14.0-cp36-cp36m-macosx_10_9_x86_64.whl Collecting six>=1.9 (from protobuf>=3.0.0->mysql-connector-python) Using cached https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl Installing collected packages: six, protobuf, mysql-connector-python Successfully installed mysql-connector-python-8.0.23 protobuf-3.14.0 six-1.15.0
インストールが完了したらlambda_function.py
含めまとめて以下コマンドでZIPにします。
$ zip -r9 ../function.zip .
ZIPファイルの作成が完了したら、function.zip
をそのままコンソールからアップロードします。
これでLambda側の設定は完了です。
EC2のセキュリティグループを編集する
作成したLambda関数からのアクセスを許可するため、EC2のセキュリティグループのインバウンドルールを編集します。
EC2に紐づけたセキュリティグループのインバウンドルールにLambdaのセキュリティグループIDを入力します。クロスアカウントのため見つかりませんと表示されていますが、Enterを押すとしっかりと認識してくれますのでご安心下さい。MySQLのポート3306ポートを指定してルールを保存します。
Lambdaを実行してみる
セキュリティグループの設定が完了したら、Lambdaを実行してみます。
テストを実行してみると、設定が正しければname : Suzuki,Satou,Kimura,Toda,Goto
とサンプルで作成した名前が結果として確認できるはずです。
まとめ
クロスアカウント上でVPCピアリングした環境でLambdaを実行したことがなかったのでやってみました。クロスアカウント先のLambdaでもしっかりセキュリティグループで接続元を指定できるのはいいですね。